﻿using black_screen_mode_server.DataCommunication;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace black_screen_mode_server
{
    /// <summary>
    /// TCP服务端
    /// </summary>
    public class TcpServerHelper : IDisposable
    {
        /// <summary>
        /// 监听套间字
        /// </summary>
        private Socket SocketS { get; set; }
        /// <summary>
        /// 连接池数列
        /// </summary>
        private List<Socket> SocketClients { get; set; }
        /// <summary>
        /// 连接数
        /// </summary>
        public int ConnectCount { get { return SocketClients.Count; } }
        /// <summary>
        /// 是否监听
        /// </summary>
        public bool isListening { get { return SocketS.IsBound; } }
        /// <summary>
        /// 监听的IP
        /// </summary>
        private string Ip { get; set; }
        /// <summary>
        /// 监听的端口
        /// </summary>
        private int Port { get; set; }
        /// <summary>
        /// 监听每次读取字节数
        /// </summary>
        private byte[] Buffer { get; set; }
        /// <summary>
        /// 最大连接数
        /// </summary>
        private int Count { get; set; }
        /// <summary>
        /// 接收消息
        /// </summary>
        public event Action<byte[], int, Socket> SocketReceive;
        /// <summary>
        /// 报错事件
        /// </summary>
        public event Action<string, Exception, Socket> SocketMessage;
        /// <summary>
        /// 连接事件
        /// </summary>
        public event Action<bool, EndPoint> ConnectEndPoints;
        /// <summary>
        /// /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ip">监听的IP</param>
        /// <param name="port">监听的端口</param>
        /// <param name="bufferLength">监听每次读取字节数,默认1MB = 1024 * 1024B</param>
        public TcpServerHelper(string ip, int port, int bufferLength = 1024 * 1024, int count = int.MaxValue)
        {
            Ip = ip;
            Port = port;
            Buffer = new byte[bufferLength];
            SocketClients = new List<Socket>();
            Count = count;
        }
        public void start()
        {
            Listen();
        }


        public void stop()
        {
            SocketS?.Close();
            foreach (Socket socket in SocketClients)
            {
                socket.Close();
            }
        }
        /// <summary>
        /// 开始监听
        /// </summary>
        /// <returns></returns>
        public async Task Listen()
        {
            try
            {
                //1.0 实例化套接字(IP4寻找协议,流式协议,TCP协议)
                SocketS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //2.0 创建IP对象
                IPAddress address = IPAddress.Parse(Ip);
                //3.0 创建网络端口,包括ip和端口
                IPEndPoint endPoint = new IPEndPoint(address, Port);
                //4.0 绑定套接字
                SocketS.Bind(endPoint);
                //5.0 设置最大连接数
                SocketS.Listen(Count);
                //6.0 循环遍历连接
                await Task.Run(() =>
                {
                    for (; ; )
                    {
                        try
                        {
                            if(DataCommunicationMng.GetInstance().GetServerRunFlag()==false)
                            {
                                Logger.Singleton.Debug("服务器关闭，停止与客户端通信！");
                                break;
                            }
                            //接收客户端连接
                            Socket SocketClient = SocketS.Accept();
                            //加入连接池数列
                            SocketClients.Add(SocketClient);
                            //获取socketClient的IP和端口
                            string clientIp = ((IPEndPoint)SocketClient.RemoteEndPoint).Address.ToString();
                            int clientPort = ((IPEndPoint)SocketClient.RemoteEndPoint).Port;

                            Logger.Singleton.Info($"客户端--{clientIp}:{clientPort}连接到服务器！");
                            //连接事件
                            SocketMessage?.Invoke($"{SocketClient.RemoteEndPoint}接入", null,SocketClient);
                            ConnectEndPoints?.Invoke(true, SocketClient.RemoteEndPoint);
                            //开始监听
                            Thread thread = new Thread(Receive);
                            thread.Start(SocketClient);
                        }
                        catch (Exception ex)
                        {
                            Logger.Singleton.Error("服务器监听错误！");
                            SocketMessage?.Invoke("服务监听出错", ex, null);
                        }
                      
                    }
                });
            }
            catch (Exception ex)
            {
                SocketMessage?.Invoke("服务监听出错", ex, null);
            }
        }


        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public void Send(byte[] buffer)
        {
            for (int index = SocketClients.Count - 1; index >= 0; index--)
            {
                try
                {
                    SocketClients[index].Send(buffer);
                }
                catch (SocketException ex)
                {
                    CloseConnect(SocketClients[index], ex);
                }
            }
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="socket">来自客户端的socket</param>
        //private void Receive(object SocketClient)
        //{
        //    Socket socketClient = (Socket)SocketClient;
        //    try
        //    {
        //        while (DataCommunicationMng.GetInstance().GetServerRunFlag())
        //        {
        //            //接收的字节数，当客户端下线时，receiveNumber=0
        //            int receiveNumber = socketClient.Receive(Buffer);

        //            //判断客户端是否下线，防止客户端下线时，服务端一直接收空消息
        //            if (receiveNumber == 0)
        //            {
        //                //获取socketClient的IP和端口
        //                string clientIp = ((IPEndPoint)socketClient.RemoteEndPoint).Address.ToString();
        //                int clientPort = ((IPEndPoint)socketClient.RemoteEndPoint).Port;

        //                Logger.Singleton.Info($"客户端--{clientIp}:{clientPort}掉线！");

        //                throw new SocketException();
        //            }

        //            //接收成功事件
        //            SocketReceive(Buffer, receiveNumber, socketClient);

        //        }
        //    }
        //    catch (SocketException ex)
        //    {
        //        CloseConnect(socketClient, ex);
        //    }
        //    catch (Exception)
        //    {
        //    }


        //}

        private void Receive(object SocketClient)
        {
            Socket socketClient = (Socket)SocketClient;
            try
            {
                while (DataCommunicationMng.GetInstance().GetServerRunFlag())
                {
                    int receiveNumber = socketClient.Receive(Buffer);

                    if (receiveNumber == 0)
                    {
                        string clientIp = ((IPEndPoint)socketClient.RemoteEndPoint).Address.ToString();
                        int clientPort = ((IPEndPoint)socketClient.RemoteEndPoint).Port;

                        Logger.Singleton.Info($"客户端--{clientIp}:{clientPort}掉线！");

                        // 不再抛异常，直接退出循环
                        break; // 或者 return;
                    }

                    // 处理接收到的数据
                    SocketReceive(Buffer, receiveNumber, socketClient);
                }
            }
            catch (SocketException ex)
            {
                // 只有真实异常才进入这里
                CloseConnect(socketClient, ex);
            }
            catch (Exception ex)
            {
                // 其他异常
                Logger.Singleton.Error("接收数据发生未知异常", ex);
                //CloseConnect(socketClient, ex);
            }
            finally
            {
                // 确保关闭连接
                CloseConnect(socketClient, null);
            }
        }


        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="ex"></param>
        private void CloseConnect(Socket socket, SocketException ex)
        {
            try
            {
                DataCommunicationMng.GetInstance().RemoveClient(socket);
                SocketMessage?.Invoke($"{socket?.RemoteEndPoint}断开连接", ex, socket);
                ConnectEndPoints?.Invoke(false, socket?.RemoteEndPoint);
                socket.Close();
                SocketClients.Remove(socket);
            }
            catch (Exception )
            {
                Logger.Singleton.Error("socket error！");
            }
         
        }

        /// <summary>
        /// 释放所有套间字
        /// </summary>
        public void Dispose()
        {
            try
            {
                SocketS?.Close();
                foreach (Socket socket in SocketClients)
                {
                    socket.Close();
                }
            }
            catch { }
        }
        /// <summary>
        /// 析构函数
        /// </summary>
        ~TcpServerHelper()
        {
            Dispose();
        }

    }

}
